package com.cy.ppj.service.rule.impl;

import com.cy.ppj.comm.constant.CacheConstants;
import com.cy.ppj.comm.constant.Constants;
import com.cy.ppj.comm.utils.SpringContextUtils;
import com.cy.ppj.dao.mapper.rule.MenuMapper;
import com.cy.ppj.dao.mapper.rule.MenuRoleMapper;
import com.cy.ppj.dao.mapper.rule.RoleMapper;
import com.cy.ppj.model.PageBean;
import com.cy.ppj.model.domian.rule.Menu;
import com.cy.ppj.model.domian.rule.Role;
import com.cy.ppj.model.query.rule.RoleAdminQuery;
import com.cy.ppj.model.vo.admin.rule.MenuAdminVO;
import com.cy.ppj.model.vo.admin.rule.MenuVO;
import com.cy.ppj.service.BaseService;
import com.cy.ppj.service.rule.RuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description: 权限
 * @author: Ocean
 * @create: 2018-07-31 17:45
 **/
@Slf4j
@Service
public class RuleServiceImpl extends BaseService implements RuleService {

    @Autowired
    private RoleMapper roleMapper;
	@Autowired
	private MenuMapper menuMapper;
	@Autowired
	private MenuRoleMapper menuRoleMapper;

    @Override
    @Transactional
	@CacheEvict(value = CacheConstants.CACHE_RULE_ROLE, allEntries = true, beforeInvocation = true)
    public void addRole(Role role) {
        role.setCreateTime(new Date());
        roleMapper.insertSelective(role);
    }

    @Override
    @Transactional
	@CacheEvict(value = CacheConstants.CACHE_RULE_ROLE, allEntries = true, beforeInvocation = true)
    public void updateRole(Role role) {
        role.setUpdateTime(new Date());
        roleMapper.updateByPrimaryKeySelective(role);
    }

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<Menu> queryMenuPatternInCache() {
		List<Menu> menus = menuMapper.selectPattern();
		return menus;
	}

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<Long> queryMenuIdInCahe(Long roleId) {
		List<Long> ids = menuRoleMapper.selectMenuIdByRoleId(roleId);
		return ids;
	}

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<MenuVO> queryMenusInCahce(Long roleId) {
    	List<Menu> list = menuMapper.selectByRoleId(roleId, Constants.ADMININTRATOR);
    	List<MenuVO> result = new ArrayList<>();
    	list.stream().filter(m -> Integer.valueOf(1).equals(m.getLevel())).forEach(m -> {
    		MenuVO menuVO = new MenuVO();
			BeanUtils.copyProperties(m, menuVO);
			menuVO.setChildren(new ArrayList<>());

			//查找子菜单
			list.stream().filter(menu -> m.getId().equals(menu.getParentId())).forEach(menu -> {
				MenuVO child = new MenuVO();
				BeanUtils.copyProperties(menu, child);

				menuVO.getChildren().add(child);
			});

			result.add(menuVO);
		});
		return result;
	}

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<MenuAdminVO> queryMenusAdminListInCache(Long roleId) {
    	//获取角色菜单权限
    	List<Long> ids = SpringContextUtils.getBean(RuleService.class).queryMenuIdInCahe(roleId);
    	//查询所有菜单
    	List<Menu> list = menuMapper.selectAll();
		List<MenuAdminVO> result = new ArrayList<>();

		list.stream().filter(m1 -> Integer.valueOf(1).equals(m1.getLevel())).forEach(m1 -> {
			//一级菜单
			MenuAdminVO first = new MenuAdminVO();
			first.setId(m1.getId());
			first.setName(m1.getName());
			first.setChecked(ids.contains(m1.getId()));
			first.setChildren(new ArrayList<>());

			//二级菜单
			list.stream().filter(m2 -> m1.getId().equals(m2.getParentId())).forEach(m2 -> {
				MenuAdminVO second = new MenuAdminVO();
				second.setId(m2.getId());
				second.setName(m2.getName());
				second.setChecked(ids.contains(m2.getId()));
				second.setChildren(new ArrayList<>());

				//三级菜单
				list.stream().filter(m3 -> m2.getId().equals(m3.getParentId())).forEach(m3 -> {
					MenuAdminVO third = new MenuAdminVO();
					third.setId(m3.getId());
					third.setName(m3.getName());
					third.setChecked(ids.contains(m3.getId()));
					third.setChildren(new ArrayList<>());

					second.getChildren().add(third);
				});

				first.getChildren().add(second);
			});

			result.add(first);
		});

		return result;
	}

	@Override
	public PageBean<Role> queryRoleAdminList(RoleAdminQuery query) {
        Role role = new Role();
		role.setName(query.getName());
		int total = roleMapper.selectCount(role);
		List<Role> list = new ArrayList<>();
		if(total > 0) {
			query.startPage();
			list = roleMapper.select(role);
		}
		return new PageBean<>(list, total);
	}

	@Override
	@Cacheable(value = CacheConstants.CACHE_RULE_ROLE)
	public List<Role> allRolesInCache() {
		List<Role> list = roleMapper.selectAll();
		list.stream().forEach(r -> {
			r.setCreateTime(null);
			r.setUpdateTime(null);
			r.setRemarks(null);
		});
		return list;
	}

	@Override
	@Transactional
	@CacheEvict(value = CacheConstants.CACHE_RULE_ROLE, allEntries = true, beforeInvocation = true)
	public void addRoleMenu(Long roleId, List<Long> menuIds) {
    	Date time = new Date();
		menuRoleMapper.insertBatch(roleId, menuIds, time);
		menuRoleMapper.deleteByUpdateTime(roleId, time);
	}

}
